func (basedMethod) funcName(parameters)(returnType) {
}
Go的func命名是採用駝峰式大小寫
,譬如:FindTheJob
。
字首大寫
代表對外暴露
,是個global function。
字首小寫
則只能在相同package
中使用。
func Variable() {
...
}
package main
import (
"fmt"
)
func main() {
a()
}
func a() {
fmt.Println("Hello World")
}
運行後可得以下結果
Hello World
回傳一個變數,要先定義回傳的變數型態
func Variable() ReturnType {
...
}
package main
import (
"fmt"
)
func main() {
fmt.Println(b())
}
func a() {
fmt.Println("Hello World")
}
func b() int {
return 1 + 2
}
運行後可得以下結果
3
func Variable() (Variable ReturnType) {
...
}
等同於在func
中做了var variable type
這件事
所以func
內的variable
可以直接取用
func d() (e string) {
e = "I am e!"
return e
}
func Variable() (ReturnType, ReturnType) {
...
}
package main
import (
"fmt"
)
func main() {
fmt.Println(c())
}
a
func a() {
fmt.Println("Hello World")
}
func b() int {
return 1 + 2
}
func c() (int, string) {
return 1 + 2, "參"
}
運行後可得結果
3 參
Struct搭配Func
func (S Struct) Variable() {
...
}
package main
import (
"fmt"
)
type Bag struct {
Wallet string
Pen string
}
func main() {
var bag Bag
bag.Pen = "BlackPen"
bag.show()
}
func a() {
fmt.Println("Hello World")
}
func b() int {
return 1 + 2
}
func c() (int, string) {
return 1 + 2, "參"
}
func (Bag *Bag) show() {
pen := Bag.Pen
fmt.Println(pen)
}
運行後可得以下結果
BlackPen
這方法讓你的物件Bag
動了起來,
他不在只是個物件,他現在會show
時展示筆的資訊。
Go的Interface類型是對其他類型行為的抽象和概括,因為Interface不會和特定的實現細節綁定一起透過該種抽象方式可以讓我們對對象更加靈活和更具有適應能力。
Go
中的interface
可以是任意值。
package main
import (
"fmt"
)
type Area interface {
Calculate() float64
}
type Rect struct {
width float64
height float64
}
func (r Rect) Calculate() float64 {
return r.height * r.width
}
func main() {
var a Area
fmt.Printf("(%T, %v) \n", a, a)
a= Rect{3, 5}
fmt.Printf("(%T, %v) \n", a, a)
fmt.Println(a.Calculate())
}
運行後可得以下結果
(<nil>, <nil>)
(main.Rect, {3 5})
15
我們可以得知
nil
Rect
Calculate()
,若在賦予struct前執行Calculate()
便會抱錯。下面我們再看一個生動的例子,讓大家更加了解interface
package main
import (
"fmt"
)
type Animal interface {
eat()
}
type Cat struct {
catName string
}
func (c Cat) eat() {
fmt.Println(c.catName, "Eat!!")
}
func main() {
var cat1 Animal = Cat{"Black Cat"}
cat1.eat()
var cat2 Animal = Cat{"White Cat"}
cat2.eat()
}
運行後可得以下結果
Black Cat Eat!!
White Cat Eat!!
型別斷言 提供存取介面實體化值的方法
試著將interface轉成該型別,並把值取出
package main
import (
"fmt"
)
func main() {
var hello interface{} = "hello"
helloStr := hello.(string)
fmt.Println(helloStr)
}
運行後可得以下結果
hello
如果給錯型別會引發Panic
package main
import (
"fmt"
)
func main() {
var hello interface{} = "hello"
helloStr := hello.(string)
fmt.Println(helloStr)
}
運行後會得以下結果
panic: interface conversion: interface {} is string, not int
goroutine 1 [running]:
main.main()
/tmp/sandbox1366433049/prog.go:9 +0x2e
所以想在不知道型別的狀況下取出介面的型別值,
可以加上ok
此一變數來驗證 動作是否成功
package main
import (
"fmt"
)
func main() {
var hello interface{} = "hello"
helloInt, ok := hello.(int)
fmt.Println(helloInt, ok)
}
運行後可得以下結果
0 false
可以用這個特殊的方法來檢驗一個物件的型別。
package main
import (
"fmt"
)
func main(){
whatType(123)
}
func whatType(i interface{}) {
switch v := i.(type) {
case int:
fmt.Println("int")
case string:
fmt.Println("string")
case bool:
fmt.Println("bool")
case nil:
fmt.Println("nil")
default:
fmt.Println("unknown", v)
}
}
運行後可得以下結果
int
i.(type)
只能夠搭配switch
使用,因此特殊。
當一個type實作了interface後,該type所建立的變數除了屬於原本type外,也屬於該interface的type,一個變數同時符合多個型別就被稱為Polymorphism 多型。
package main
import (
"fmt"
)
type Answer interface {
getSalary() int
}
type Question struct {
a, b int
}
func (q Question) Add() int {
return q.a + q.b
}
type Student struct {
firstName, lastName string
question Question
}
func main() {
flynn := Student{
firstName: "Flynn",
lastName: "Sun",
question: Question{
30, 20,
},
}
fmt.Println("Student's Answer", flynn.question.Add())
}
舉例來說,這裡先定義了 Salaried 這個 interface type,接著 Salary 這個 struct type 實作了 Salaried 中定義的 method signatures,因此 Salary 這個 struct type 也同時符合了 Salaried interface type,這樣的行為稱作 polymorphism。
舉例來說,這裡我們
這行為被稱作polymorphism
綜合以上好處,interface在Golnag的標準庫當中是非常常用到的,像是定義檔案的讀寫的Reader
, Writer
interface等
type Reader interface {
Read(p []byte) (n int, err error)
}
type Writer interface {
Write(p []byte) (n int, err error)
}
兩者皆利用了os.File
實現其interface,已完成檔案的讀與寫
Function與Interface基本上已經是Go開發中不可或缺的元素了,尤其是Function!
但這邊介紹的用法也只是冰山一角,希望大家入門後可以再透過實作與練習再去更深入它。